package cn.yunyichina.provider.bed.service.impl;

import cn.yunyichina.provider.bed.dao.InpatientRecordDao;
import cn.yunyichina.provider.bed.dao.InpatientRecordListDao;
import cn.yunyichina.provider.bed.thread.InpatientFeeSaveRunnable;
import cn.yunyichina.provider.bed.thread.InpatientRecordRunnable;
import cn.yunyichina.provider.bed.vo.BedFeeResponseVo;
import cn.yunyichina.provider.bed.vo.BedVo;
import cn.yunyichina.provider.bed.vo.DailyBedFeeVoResponseVo;
import cn.yunyichina.provider.framework.dubbo.service.HisifaceService;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.ResponseObject;
import cn.yunyichina.provider.iface.entity.hisiface.bed.*;
import cn.yunyichina.utils.convert.JsonUtils;
import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.FutureTask;

/**
 * Created by Administrator on 2016/12/12 0012.
 * 住院功能
 */
@Service("inbedServiceImpl")
public class InBedServiceImpl {
    private static final Logger logger = LoggerFactory.getLogger(InBedServiceImpl.class);
    @Autowired
    private InpatientRecordDao inpatientRecordDao;
    @Autowired
    private InpatientRecordListDao inpatientRecordListDao;

    //日清单
    public ResponseObject getInBedFee(String data) {
        logger.info("getInBedFee data: " + data);
        ResponseObject response = new ResponseObject();
        BedVo requestVo = JsonUtils.parseObject(data, BedVo.class);

        if (StringUtils.isBlank(requestVo.getPatientId())||StringUtils.isBlank(requestVo.getAdmissionNo())
                ||StringUtils.isBlank(requestVo.getInTime())
                ||StringUtils.isBlank(requestVo.getCostDate())||StringUtils.isBlank(requestVo.getCostDate())
                ||StringUtils.isBlank(requestVo.getCostType())||StringUtils.isBlank(requestVo.getHospitalCode())){
            response.setResultCodeAndMessage("14002","hospitalCode,住院记录ID,住院号，住院次数,费用日期,cost_type不能为空不得为空");
            return response;
        }


        DailyBedFeeVoResponse dailyBedFeeVoResponse =null;
        DailyBedFeeVoResponseVo dailyBedFeeVoResponseVo = new DailyBedFeeVoResponseVo();

        try {
            DailyBedFeeVo dailyBedFeeVo = new DailyBedFeeVo();
            dailyBedFeeVo.setHospitalCode(requestVo.getHospitalCode());
            dailyBedFeeVo.setAdmissionNo(requestVo.getAdmissionNo());
            dailyBedFeeVo.setPatientId(requestVo.getPatientId());
            dailyBedFeeVo.setInTime(requestVo.getInTime());
            dailyBedFeeVo.setCostDate(requestVo.getCostDate());

            logger.info("调用前置机开始日清单开始");
            ResCommon<DailyBedFeeVoResponse> dailyBedFee = HisifaceService.getHisifaceClient().getDailyBedFee(dailyBedFeeVo);
            if (!"0".equals(dailyBedFee.getResultCode())){
                response.setResultCodeAndMessage("14998", dailyBedFee.getResultMessage());
                return response;
            }

            dailyBedFeeVoResponse = dailyBedFee.getResult();

            dailyBedFeeVoResponseVo.setBalance(dailyBedFeeVoResponse.getBalance());
            dailyBedFeeVoResponseVo.setBedNo(dailyBedFeeVoResponse.getBedNo());
            dailyBedFeeVoResponseVo.setDeptName(dailyBedFeeVoResponse.getDeptName());
            dailyBedFeeVoResponseVo.setDescription(dailyBedFeeVoResponse.getDescription());
            dailyBedFeeVoResponseVo.setTodayAmount(dailyBedFeeVoResponse.getTodayAmount());

            List<BedFeeResponseVo> bedFeeVoList = new ArrayList<>();
            for (BedFee bedFee :dailyBedFeeVoResponse.getBedFeeItems()){
                BedFeeResponseVo bedFeeVo = new BedFeeResponseVo();
                bedFeeVo.setCostAmount(bedFee.getCostAmount());
                bedFeeVo.setCostName(bedFee.getCostName());
                bedFeeVo.setCostType(bedFee.getCostType());
                bedFeeVoList.add(bedFeeVo);
            }

            dailyBedFeeVoResponseVo.setBedFeeItems(bedFeeVoList);
            logger.info("调用前置机开始日清单结束: result={}", new Object[] {JsonUtils.toJsonString(dailyBedFeeVoResponse)});

        } catch (Exception ex) {
            response.setResultCodeAndMessage("14999"," 系统异常");
            return  response;
        }

        try {
            DailyBedFeeDetailVo dailyBedFeeDetailVo = new DailyBedFeeDetailVo();
            dailyBedFeeDetailVo.setHospitalCode(requestVo.getHospitalCode());
            dailyBedFeeDetailVo.setAdmissionNo(requestVo.getAdmissionNo());
            dailyBedFeeDetailVo.setPatientId(requestVo.getPatientId());
            dailyBedFeeDetailVo.setInTime(requestVo.getInTime());
            dailyBedFeeDetailVo.setCostDate(requestVo.getCostDate());
            dailyBedFeeDetailVo.setCostType(requestVo.getCostType());

            logger.info("调用前置机开始日清单明细列表开始");
            ResCommon<List<DailyBedFeeDetailVoResponse>> dailyBedFeeDetail = HisifaceService.getHisifaceClient().getDailyBedFeeDetail(dailyBedFeeDetailVo);
            if (!"0".equals(dailyBedFeeDetail.getResultCode())){
                response.setResultCodeAndMessage("14998", dailyBedFeeDetail.getResultMessage());
                return response;
            }

            List<DailyBedFeeDetailVoResponse> dailyBedFeeDetailVoResponseList = dailyBedFeeDetail.getResult();
            logger.info("调用前置机开始日清单明细列表结束 result={}",new Object[]{JsonUtils.toJsonString(dailyBedFeeDetailVoResponseList)});

            Map<String ,List<BedFeeDetail>> bedFeeDatailMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(dailyBedFeeDetailVoResponseList)){
                for (DailyBedFeeDetailVoResponse detailVoResponse :dailyBedFeeDetailVoResponseList){
                    bedFeeDatailMap.put(detailVoResponse.getCostType(),detailVoResponse.getBedFeeDetails());
                }
            }

            for (BedFeeResponseVo bedFee : dailyBedFeeVoResponseVo.getBedFeeItems()){
                List<BedFeeDetail> bedFeeDetails = bedFeeDatailMap.get(bedFee.getCostType());
                bedFee.setBedFeeDetails(bedFeeDetails);
            }

            //保存日清单信息
            FutureTask futureTask = new FutureTask(new InpatientFeeSaveRunnable(requestVo, dailyBedFeeVoResponseVo));
            Thread thread = new Thread(futureTask);
            thread.start();

            logger.info("日清单基本信息 ,日清单明细列表 合并后返回结果 result ={}", new Object[] {JsonUtils.toJsonString(dailyBedFeeVoResponseVo)});

            response.setResultCodeAndMessageAndResult("0","成功",dailyBedFeeVoResponseVo);
            return response;

        } catch (Exception ex) {
            response.setResultCodeAndMessage("14999"," 系统异常");
            return  response;
        }

    }

    /*
        住院记录 yyt.bed.inbed.records.get
     status   0：住院中 1：已出院  不传全部
     */
    public ResponseObject getInBedRecords(String data,String sessionId,String appId) {
        logger.info("住院记录 getInBedRecords data: "+data);
        ResponseObject response = new ResponseObject();
        BedVo requestVo = JsonUtils.parseObject(data, BedVo.class);
        if (StringUtils.isBlank(requestVo.getHospitalCode())){
            response.setResultCodeAndMessage("14002","hospitalCode");
            return response;
        }

        if ((StringUtils.isBlank(requestVo.getPatCardNo())||StringUtils.isBlank(requestVo.getPatCardType())) && StringUtils.isBlank(requestVo.getAdmissionNo())){
            response.setResultCodeAndMessage("14002","就诊卡号,就诊卡类型 和住院号不能同时为空");
            return response;
        }
        try {
            BedRecordsVo bedRecordsVo = new BedRecordsVo();
            bedRecordsVo.setHospitalCode(requestVo.getHospitalCode());
            bedRecordsVo.setAdmissionNo(requestVo.getAdmissionNo());
            bedRecordsVo.setPatCardType(requestVo.getPatCardType());
            bedRecordsVo.setPatCardNo(requestVo.getPatCardNo());
            Map<String,String> mapExtraParam = new HashMap<>();
            //和平县医院要求扩展字段写入患者姓名
            if (org.apache.commons.lang.StringUtils.isNotBlank(requestVo.getPatName())) {
            	mapExtraParam.put("pat_name", requestVo.getPatName());
            }
            if(!StringUtils.isBlank(requestVo.getPatIdNo())){
                //连平县人民医院扩展字段增加身份证
                mapExtraParam.put("pat_id_type","1");
                mapExtraParam.put("pat_id_no", requestVo.getPatIdNo());
            }
            bedRecordsVo.setExtendParams(JsonUtils.toJsonString(mapExtraParam));
            
            logger.info("调用调度中心开始");
            ResCommon<List<BedRecordsVoResponse>> bedRecords  = HisifaceService.getHisifaceClient().getBedRecords(bedRecordsVo);
            logger.info("调用调度中心结束");
            if (!"0".equals(bedRecords.getResultCode())){
                logger.info("调用调度中心产生异常"+ bedRecords.getResultMessage());
                response.setResultCodeAndMessage("14998", bedRecords.getResultMessage());
                return response;
            }
            logger.info("调用调度中心返回 "+JsonUtils.toJsonString(bedRecords));
            List<BedRecordsVoResponse> bedRecordsVoResponseResult = new ArrayList<>();

            List<BedRecordsVoResponse> bedRecordsVoResponseList = bedRecords.getResult();

            if (CollectionUtils.isNotEmpty(bedRecordsVoResponseList)){
                logger.info("调用调度中心结束"+bedRecordsVoResponseList);
                //0：住院中 1：已出院  不传全部
                if ("0".equals(requestVo.getStatus())){
                    for(BedRecordsVoResponse bed:bedRecordsVoResponseList){
                        logger.info("请求住院中记录===============");
                        if ("0".equals(bed.getStatus())){
                            bedRecordsVoResponseResult.add(bed);
                        }
                    }
                }else if("1".equals(requestVo.getStatus())){
                    logger.info("请求已出院记录===============");
                    for(BedRecordsVoResponse bed:bedRecordsVoResponseList){
                        if ("1".equals(bed.getStatus())){
                            bedRecordsVoResponseResult.add(bed);
                        }
                    }
                }else {
                    logger.info("请求所有住院记录===============");
                    bedRecordsVoResponseResult = bedRecordsVoResponseList;
                }
                requestVo.setAppId(appId);
                Thread  inpatientRecordThread = new Thread(new InpatientRecordRunnable(bedRecordsVoResponseList,requestVo));
                inpatientRecordThread.start();
            }

            response.setResultCodeAndMessageAndResult("0","成功",bedRecordsVoResponseResult);

        } catch (Exception ex) {
            response.setResultCodeAndMessage("14999"," 系统异常");
            return  response;
        }

        return response;
    }



    /*
         住院医嘱
     */
    public ResponseObject getInBedAdvice(String data) {
        logger.info("getInBedMedOrders data: "+data);
        ResponseObject response = new ResponseObject();
        BedVo requestVo = JsonUtils.parseObject(data, BedVo.class);

        if (StringUtils.isBlank(requestVo.getPatientId())){
            if (StringUtils.isBlank(requestVo.getAdmissionNo())||StringUtils.isBlank(requestVo.getInTime())){
                response.setResultCodeAndMessage("14002","住院记录ID为空时，住院号和住院次数不得为空");
                return response;
            }
        }
        if (StringUtils.isBlank(requestVo.getAdmissionNo())||StringUtils.isBlank(requestVo.getInTime())){
            if (StringUtils.isBlank(requestVo.getPatientId())){
                response.setResultCodeAndMessage("14002","住院号和住院次数为空时，住院记录ID不得为空");
                return response;
            }
        }

        if (requestVo.getStatus() ==null){
            response.setResultCodeAndMessage("14002","status 不能为空");
            return response;
        }


        try {
            BedAdviceVo bedAdviceVo = new BedAdviceVo();
            bedAdviceVo.setHospitalCode(requestVo.getHospitalCode());
            bedAdviceVo.setAdmissionNo(requestVo.getAdmissionNo());
            bedAdviceVo.setInTime(requestVo.getInTime());
            bedAdviceVo.setPatientId(requestVo.getPatientId());
            bedAdviceVo.setStatus(requestVo.getStatus());

            ResCommon<BedAdviceVoResponse> bedadviceResponse  = HisifaceService.getHisifaceClient().getBedAdvice(bedAdviceVo);
            if (!"0".equals(bedadviceResponse.getResultCode())){
                response.setResultCodeAndMessage("14998", bedadviceResponse.getResultMessage());
                return response;
            }

            BedAdviceVoResponse bedAdviceVoResponse = bedadviceResponse.getResult();
            response.setResultCodeAndMessageAndResult("0","成功",bedAdviceVoResponse);

        } catch (Exception ex) {
            response.setResultCodeAndMessage("14999"," 系统异常");
            return  response;
        }

        return response;
    }


    /**
     * 出入院-住院费用查询
     * @param data
     * @param sessionId
     * @return
     */
    public ResponseObject getInbedBedfee(String data, String sessionId){
        //定义返回结果
        ResponseObject response = new ResponseObject();
        BedFeeVoResponse bedFee = new BedFeeVoResponse();

        //定义返回码和返回信息
        String resultCode = "0";
        String resultMessage = "执行成功";

        try {
            //获取入参
            logger.info("【出入院-住院费用查询】开始, 请求="+data,",sessionId=" + sessionId);
            BedVo bedVo = JsonUtils.parseObject(data, BedVo.class);

            //检查参数合法性
            boolean check = true;
            if(StringUtils.isBlank(bedVo.getAdmissionNo()) && StringUtils.isBlank(bedVo.getPatientId())){
                check = false;
                resultCode = "14002";
                resultMessage = "参数有误:" + "admission_no住院号和patient_id住院记录ID不能同时为空";
            }

            //检查不通过，结束流程
            if(!check){
                return response;
            }

            BedFeeVo bedFeeVo = new BedFeeVo();
            bedFeeVo.setHospitalCode(bedVo.getHospitalCode());
            bedFeeVo.setPatientId(bedVo.getPatientId());
            bedFeeVo.setAdmissionNo(bedVo.getAdmissionNo());
            //不能写死 add by zd
            bedFeeVo.setInTime(bedVo.getInTime());
            ResCommon<BedFeeVoResponse> bedFeeVoResponse = HisifaceService.getHisifaceClient().getBedFee(bedFeeVo);

            //如果访问his失败
            if (!"0".equals(bedFeeVoResponse.getResultCode())){
                response.setResultCodeAndMessage("14998",bedFeeVoResponse.getResultMessage());
            }else{
                bedFee = bedFeeVoResponse.getResult();
            }
        } catch (Exception e) {
            resultCode = "14999";
            resultMessage = "系统异常:" + e.getMessage();
            e.printStackTrace();
        } finally {
            //组装返回结果
            response.setResultCodeAndMessageAndResult(resultCode, resultMessage, JsonUtils.toJsonString(bedFee));
            logger.info("【出入院-住院费用查询】结束, 返回结果=" + JsonUtils.toJsonString(response));
            return response;
        }
    }

    /**
     * 出入院-住院押金补缴记录查询
     * @param data
     * @param sessionId
     * @return`
     */
    public ResponseObject getInbedDepositrecords(String data, String sessionId){
        //定义返回结果
        ResponseObject response = new ResponseObject();
        List<DepositRecordsVoResponse> depositRecords = new ArrayList<>();

        //定义返回码和返回信息
        String resultCode = "0";
        String resultMessage = "执行成功";

        try {
            //获取入参
            logger.info("【出入院-住院押金补缴记录查询】开始, 请求="+data,",sessionId=" + sessionId);
            BedVo bedVo = JsonUtils.parseObject(data, BedVo.class);

            //检查参数合法性
            boolean check = true;
            if(StringUtils.isBlank(bedVo.getAdmissionNo())){
                check = false;
                resultCode = "14002";
                resultMessage = "参数有误:" + "admission_no住院号不能为空";
            }

            //检查不通过，结束流程
            if(!check){
                return response;
            }

            DepositRecordsVo depositRecordsVo = new DepositRecordsVo();
            depositRecordsVo.setHospitalCode(bedVo.getHospitalCode());
            depositRecordsVo.setAdmissionNo(bedVo.getAdmissionNo());
            depositRecordsVo.setPayMode("5");
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//            depositRecordsVo.setBeginDate(sdf.format(new Date()));
//            depositRecordsVo.setEndDate(sdf.format(new Date()));
            depositRecordsVo.setBeginDate(bedVo.getBeginDate());
            depositRecordsVo.setEndDate(bedVo.getEndDate());
            //假如传入住院次数，则放到扩展字段传给前置机(广中医)
            if(StringUtils.isNotEmpty(bedVo.getInTime())){
                Map<String, Object> extMap = new HashMap<String, Object>();
                extMap.put("in_time", bedVo.getInTime());
                depositRecordsVo.setExtendParams(JsonUtils.toJsonString(extMap));
            }
            ResCommon<List<DepositRecordsVoResponse>> depositRecordsVoResponse = HisifaceService.getHisifaceClient().getDepositRecords(depositRecordsVo);

            //如果访问his失败
            if (!"0".equals(depositRecordsVoResponse.getResultCode())){
                response.setResultCodeAndMessage("14998",depositRecordsVoResponse.getResultMessage());
            }else{
                depositRecords = depositRecordsVoResponse.getResult();
            }
        } catch (Exception e) {
            resultCode = "14999";
            resultMessage = "系统异常:" + e.getMessage();
            e.printStackTrace();
        } finally {
            //组装返回结果
            response.setResultCodeAndMessageAndResult(resultCode, resultMessage, JsonUtils.toJsonString(depositRecords));
            logger.info("【出入院-住院押金补缴记录查询】结束, 返回结果=" + JsonUtils.toJsonString(response));
            return response;
        }
    }

}
